package com.example.back.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.example.back.dto.ExcelAdmin;
import com.example.back.dto.req.AdminEditReq;
import com.example.back.dto.req.AdminReq;
import com.example.back.dto.resp.AdminResp;
import com.example.back.dto.resp.HospitalDepartmentListResp;
import com.example.back.dto.resp.HospitalDepartmentResp;
import com.example.back.dto.resp.RolesResp;
import com.example.back.jpa.AdminRepository;
import com.example.back.jpa.HospitalDepartmentRepository;
import com.example.back.jpa.SysRoleAdminRepository;
import com.example.back.jpa.SysRolesRepository;
import com.example.back.mapper.AdminMapper;
import com.example.back.service.AdminService;
import com.example.back.utils.ExcelUtils;
import com.example.common.entity.Admin;
import com.example.common.entity.HospitalDepartment;
import com.example.common.entity.RoleAdmin;
import com.example.common.entity.Roles;
import com.example.common.support.ApiException;
import com.example.common.utils.CheckUtils;
import com.example.common.utils.IdUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import org.javers.spring.annotation.JaversAuditable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户管理
 */
@Service
public class AdminServiceImpl implements AdminService {


    @Resource
    private AdminMapper adminMapper;

    @Resource
    private AdminRepository adminRepository;

    @Resource
    private SysRoleAdminRepository sysRoleAdminRepository;

    @Resource
    private HospitalDepartmentRepository hospitalDepartmentRepository;

    @Resource
    private SysRolesRepository sysRolesRepository;

    @Resource
    private ExcelUtils excelUtils;
    

    /**
     * 获取账号管理列表
     * @param req
     * @return
     */
    @Override
    public PageInfo<AdminResp> list(AdminReq req) {
        CheckUtils.checkNull(req, new ApiException(10000, "对象不能为空"));
        //分页页码，默认1页
        int pageNumber = null == req.getPage() ? 1 : req.getPage();
        //分页条数，默认10条
        int pageSize = null == req.getLimit() ? 10 : req.getLimit();
        //角色名称
        String name = req.getName();
        //角色id
        Long rId = req.getID();
        return PageHelper
                .startPage(pageNumber, pageSize)
                .doSelectPageInfo(() -> adminMapper.findSysAdminByUserName(name, rId));
    }


    /**
     * 新增和修改管理账号
     * @param req
     * @return
     */
    @Override
    @JaversAuditable
    @Transactional(rollbackFor = Exception.class)
    public Object commitSave(AdminEditReq req) {
        CheckUtils.checkNull(req, new ApiException(10000, "对象不能为空"));

        CheckUtils.checkNull(req.getPassword(), new ApiException(1, "请输入密码"));
        CheckUtils.checkNull(req.getUsername(), new ApiException(1, "清输入手机号码"));
        CheckUtils.checkNull(req.getName(), new ApiException(1, "姓名不存在"));

        boolean isMatch = ReUtil.isMatch("^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[^a-zA-Z0-9]).{8,}$", req.getPassword());

        if(isMatch==false){
            throw new ApiException(1, "密码至少8位，并包含 数字,字母,符号");
        }
        Date date = DateUtil.date();
        DateTime newDate = DateUtil.offsetMonth(date, 3);

        List<RoleAdmin> admins = sysRoleAdminRepository.findByUid(req.getID());
        if(req.getID() == 0){

            Admin admin = adminRepository.findByUsername(req.getUsername());
            if(admin!=null){
                throw new ApiException(1, "手机号码已存在");
            }
            Admin obj = new Admin();
            obj.setId(IdUtils.generateId());
            obj.setUsername(req.getUsername());
            obj.setName(req.getName());
            obj.setPassword( DigestUtil.md5Hex(req.getPassword()));
            obj.setDisable(false);
            obj.setCreateTime(new Date());
            obj.setDepartID(req.getDepartID());
            obj.setDepartName(req.getDepartName());
            obj.setEditTime(newDate);

            if (admins.size()==0){
                RoleAdmin roleAdmin = new RoleAdmin();
                roleAdmin.setId(IdUtils.generateId());
                roleAdmin.setUid(obj.getId());
                roleAdmin.setRid(req.getRID());
                sysRoleAdminRepository.save(roleAdmin);
            }

            return adminRepository.save(obj);

        }else{
            Admin objs = adminRepository.findById(req.getID()).orElse(null);
            objs.setName(req.getName());
            objs.setDepartID(req.getDepartID());
            objs.setDepartName(req.getDepartName());
            objs.setPassword(DigestUtil.md5Hex(req.getPassword()));
            objs.setEditTime(newDate);
            RoleAdmin objRole = admins.get(0);

            if(objRole.getRid() != req.getRID()){
                objRole.setRid(req.getRID());
                sysRoleAdminRepository.save(objRole);
            }

            return adminRepository.save(objs);
        }
    }


    /**
     * 禁用管理账户
     * @param req
     * @return
     */
    @Override
    @JaversAuditable
    public Object updateDisable(AdminReq req) {

        CheckUtils.checkNull(req, new ApiException(1, "对象不能为空"));

        Admin objs = adminRepository.findById(req.getID()).orElse(null);
        if(objs==null){
            throw new ApiException(1, "账号ID不匹配");
        }

        objs.setDisable(!objs.getDisable());
        objs = adminRepository.save(objs);
        return objs;
    }

    // private void tttttt(long id){
    //     QueryBuilder jqlQuery = QueryBuilder.anyDomainObject();
    //     List<Change> changes = javers.findChanges(jqlQuery.build());
    //     // System.out.println("changes123"+changes);
    //     // changes.stream().forEach(e -> {
    //     //     System.out.println(e.toString());
    //     // });
    //     String changeLog = javers.processChangeList(changes, new SimpleTextChangeLog());
    //     System.out.println(changeLog);
    // }

    // public void testSnapshotHistory(long id){
    //     List<CdoSnapshot> snapshots = javers.findSnapshots(QueryBuilder.byInstanceId(id, Admin.class).build());
    //     System.out.println("aaa:"+snapshots);
    // }


    /**
     * 导出账号
     * @param req
     * @return
     */
    @Override
    public Object ExportXls(AdminReq req) {

       List<AdminResp> objs=adminMapper.findSysAdminByUserName(req.getName(), req.getID());
       if(objs==null){
           throw new ApiException(1, "数据不存在");
       }
        List<ExcelAdmin> list = new ArrayList<>();

        for (AdminResp adminResp: objs) {

            ExcelAdmin excelAdmin =  new ExcelAdmin();
            excelAdmin.setName(adminResp.getName());
            excelAdmin.setUserName(adminResp.getUsername());
            excelAdmin.setRoleName(adminResp.getRName());
            excelAdmin.setDepartName(adminResp.getDepartName());
            excelAdmin.setDisable(adminResp.getDisable()==true?"禁用":"启用");
            String formatDateTime = DateUtil.formatDateTime(adminResp.getCreateTime());
            excelAdmin.setCreateTime(formatDateTime);
            list.add(excelAdmin);
        }
        String now = DateUtil.now();
        String fileName =  "cash_" + now;
        try {
            excelUtils.excelExport(ExcelAdmin.class,list,fileName);
        }catch (Exception e){
            throw  new ApiException(1,e.getMessage());
        }
        return null;
    }

    /**
     * 删除管理账户
     * @param req
     * @return
     */
    @Override
    @JaversAuditable
    @Transactional(rollbackFor = Exception.class)
    public Object commitDel(AdminReq req) {

        Admin objs = adminRepository.findById(req.getID()).orElse(null);
        if(objs ==null){
            throw new ApiException(1, "账号不存在");
        }
        List<RoleAdmin> admins = sysRoleAdminRepository.findByUid(req.getID());
        if(admins == null){
            throw new ApiException(1, "角色不存在");
        }

        adminRepository.deleteById(objs.getId());
        sysRoleAdminRepository.deleteAll(admins);
        return null;
    }

    /**
     * 角色科室分类
     * @return
     */
    @Override
    public HospitalDepartmentListResp ClassIficationList() {

        List<Roles> Roleslist=sysRolesRepository.findAll();
        List<HospitalDepartment> Departmentlist = hospitalDepartmentRepository.findByPdId(0L);
        HospitalDepartmentListResp hospitalDepartmentListResp = new HospitalDepartmentListResp();

        List<HospitalDepartmentResp> deptList =  Departmentlist.stream().map(m->{
            HospitalDepartmentResp resp = new HospitalDepartmentResp();
            resp.setName(m.getName());
            resp.setID(m.getId());
            BeanUtil.copyProperties(m,resp);
            return resp;
        }).collect(Collectors.toList());

        List<RolesResp> RotList =  Roleslist.stream().map(m->{
            RolesResp resp = new RolesResp();
            BeanUtil.copyProperties(m,resp);
            return resp;
        }).collect(Collectors.toList());

        hospitalDepartmentListResp.setRoleslist(RotList);
        hospitalDepartmentListResp.setDepartmentlist(deptList);
        return hospitalDepartmentListResp;
    }
}
